home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / pstools / multiprint.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  11.1 KB  |  421 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18. Multiprint prints a file as multiple pages condensed on a single printed
  19. page.  It is called as follows:
  20.  
  21.     multiprint [-f bodyfont] [-F titlefont] [-p <factor>] [-P printer] file(s)
  22.  
  23. also -1 is a synonym for -p 1, -2 for -p 2, .. -9 for -p 9.
  24.  
  25. Multiprint prints a square array of pages <factor> on a side.  If <factor>
  26. is 2, 4 pages are printed, if 3, 9 are printed, etc.  Any positive integer
  27. value is valid, although it is pretty hard to read if <factor> is larger
  28. than 3.
  29.  
  30. The program is probably not the most robust in the world, and currently
  31. assumes that your lp command prints to an Apple laser writer.  All the source
  32. is in multiprint.c, and you are welcome to hack on it.  The stuff printed by
  33. the routine printheaderstuff() can easily be modified to change the
  34. appearance of all the printed pages.  The header data assumes that an 8 1/2
  35. by 11 inch page is being printed, with all the actual text at least 1/2 inch
  36. from the boundary.
  37.  
  38. The files cz4 and cz9 are simple shell scripts that print a list of files 4
  39. or 9 pages at a time, respectively.
  40.  
  41. I assume everything will work on any machine, although I have only tried it
  42. on a 3000.
  43.  
  44.   -- Tom Davis, Silicon Graphics
  45.  
  46. Addendum:
  47.  
  48.     Added command line argument parsing.
  49.     Made sure temporary files are unique.
  50.  
  51.     -- Greg Couch, U.C. Berkeley
  52.  
  53.     (6/10/88) Modified the PostScript output so that the printing will
  54.     be much more efficient.
  55.  
  56.     -- Tom Davis
  57.  
  58.     (7/6/88) Use Adobe meta-comments for pages and prologs so filters like
  59.     psrev can reverse pages only if needed (no longer uses temporary files).
  60.     Improved BSD lpr vs. Sys V lp support.
  61.  
  62.     -- Greg Couch, U.C. San Francisco
  63.  
  64. Todo:
  65.  
  66.     When using proportional fonts need tabs to go to fixed positions.
  67.  
  68. */
  69.  
  70. #include <stdio.h>
  71.  
  72. extern char    *ctime(), *getenv();
  73. extern long    time();
  74. extern int    optind;
  75. extern char    *optarg;
  76.  
  77. int    pagefactor;
  78. char    *printer;
  79. char    *bodyfont, *titlefont;
  80. int    pages_by_row;
  81.  
  82. int    line;
  83. char    *timestr;
  84. FILE    *printfile, *outputfile;
  85. int    ordinal;
  86. # ifdef BSDLPR
  87. int    no_burst;
  88. # endif
  89. int    to_stdout;
  90.  
  91. main(argc, argv)
  92. int argc;
  93. char **argv;
  94. {
  95.     long    clock;
  96.     int     i;
  97.     char    buf[100];
  98.     int     c;
  99.  
  100.     /* defaults */
  101.     pagefactor = 2;
  102.     printer = 0;
  103. # ifdef BSDLPR
  104.     if ((printer = getenv("PRINTER")) == NULL)
  105. # else
  106.     if ((printer = getenv("LPDEST")) == NULL)
  107. # endif
  108.     titlefont = "Courier-Bold";
  109.     bodyfont = "Courier";
  110.     pages_by_row = 0;
  111.  
  112.     /* parse arguments */
  113.     while ((c = getopt(argc, argv,
  114. # ifdef BSDLPR
  115.         "123456789f:F:p:P:rsh"
  116. # else
  117.         "123456789f:F:p:d:rs"
  118. # endif
  119.         )) != EOF) {
  120.     switch (c) {
  121.  
  122.     case '1': case '2': case '3':
  123.     case '4': case '5': case '6':
  124.     case '7': case '8': case '9':
  125.         pagefactor = c - '0';
  126.         break;
  127.  
  128.     case 'f':
  129.         bodyfont = optarg;
  130.         break;
  131.  
  132.     case 'F':
  133.         titlefont = optarg;
  134.         break;
  135.  
  136.     case 'p':
  137.         pagefactor = atoi(optarg);
  138.         if (pagefactor < 1)
  139.         pagefactor = 1;
  140.         break;
  141.     
  142. # ifdef BSDLPR
  143.     case 'P':
  144. # else
  145.     case 'd':
  146. # endif
  147.         printer = optarg;
  148.         break;
  149.  
  150.     case 'r':
  151.         pages_by_row = 1;
  152.         break;
  153.  
  154. # ifdef BSDLPR
  155.     case 'h':
  156.         no_burst = 1;
  157.         break;
  158. # endif
  159.  
  160.     case 's':
  161.         to_stdout = 1;
  162.         break;
  163.  
  164.     default:
  165.         (void) fprintf(stderr, "usage:  %s [options] [files(s)]\n",
  166.             argv[0]);
  167.         (void) fprintf(stderr, "options: (defaults)\n");
  168.         (void) fprintf(stderr, "\t-p <page factor>\t(2)\n");
  169. # ifdef BSDLPR
  170.         (void) fprintf(stderr, "\t-P <postscript printer>\t(PostScript)\n");
  171.         (void) fprintf(stderr, "\t-h\tsupress printing of burst page\n");
  172. # else
  173.         (void) fprintf(stderr, "\t-d <postscript printer>\t(PostScript)\n");
  174. # endif
  175.         (void) fprintf(stderr, "\t-f <text font>\t\t(Courier)\n");
  176.         (void) fprintf(stderr, "\t-F <title font>\t\t(Courier-Bold)\n");
  177.         (void) fprintf(stderr, "\t-s\toutput to stdout\t\t(spool)\n");
  178.         (void) fprintf(stderr, "\t-r\toutput pages in row order\n");
  179.         (void) fprintf(stderr, "\t-1\tis the same as -p1\n");
  180.         (void) fprintf(stderr, "\t-2\tis the same as -p2\n");
  181.         (void) fprintf(stderr, "\t...\n");
  182.         (void) fprintf(stderr, "\t-9\tis the same as -p9\n");
  183.         return 1;
  184.     }
  185.     }
  186.  
  187.     clock = time((long *) 0);
  188.     timestr = ctime(&clock);
  189.     timestr[strlen(timestr) - 1] = '\0';    /* zap trailing newline */
  190.  
  191.     if (to_stdout)
  192.     outputfile = stdout;
  193.     else {
  194. # ifdef BSDLPR
  195.     if(printer) 
  196.         (void) sprintf(buf, "lpr%s -P%s", no_burst ? " -h" : "", printer);
  197.     else
  198.         (void) sprintf(buf, "lpr%s ", no_burst ? " -h" : "");
  199.     if ((outputfile = popen(buf, "w")) == NULL) {
  200.         (void) fprintf(stderr, "unable to execute lpr command\n");
  201.         return 1;
  202.     }
  203. # else
  204.     if(printer) 
  205.         (void) sprintf(buf, "lp -d%s -o\"duplex 1\"", printer);
  206.     else
  207.         (void) sprintf(buf, "lp -o\"duplex 1\"");
  208.     if ((outputfile = popen(buf, "w")) == NULL) {
  209.         (void) fprintf(stderr, "unable to execute lp command\n");
  210.         return 1;
  211.     }
  212. # endif
  213.     }
  214.  
  215.     printheaderstuff();
  216.  
  217.     if (argc == optind) {
  218.     printfile = stdin;
  219.     printnextfile("stdin");
  220.     } else {
  221.     for (i = optind; i < argc; i++) {
  222.         if ((printfile = fopen(argv[i], "r")) == NULL) {
  223.         (void) fprintf(stderr, "couldn't open %s\n", argv[i]);
  224.         continue;
  225.         }
  226.         printnextfile(argv[i]);
  227.         (void) fclose(printfile);
  228.     }
  229.     }
  230.  
  231.     printtrailerstuff();
  232.  
  233.     if (!to_stdout)
  234.     (void) pclose(outputfile);
  235.     return 0;
  236. }
  237.  
  238. printnextfile(title)
  239. char *title;
  240. {
  241.     int row, col;
  242.     long pagenumber = 1;
  243.  
  244.     while (1) {
  245.     ordinal += 1;
  246.     (void) fprintf(outputfile, "%%%%Page: ? %d\n", ordinal);
  247.     if (pages_by_row) {
  248.         for (row = 0; row < pagefactor; row++)
  249.         for (col = 0; col < pagefactor; col++)
  250.             if (printpage(row, col, title, pagenumber++))
  251.             return;
  252.     } else {
  253.         for (col = 0; col < pagefactor; col++)
  254.         for (row = 0; row < pagefactor; row++)
  255.             if (printpage(row, col, title, pagenumber++))
  256.             return;
  257.     }
  258.     (void) fprintf(outputfile, "showpage\n");
  259.     }
  260. }
  261.  
  262. printpage(row, col, title, pagenumber)
  263.     int row, col;
  264.     char *title;
  265.     long pagenumber;
  266. {
  267.     char buffer[BUFSIZ];
  268.     char outbuf[BUFSIZ];
  269.     static int insideline = 0;
  270.     static int ordinal = 1;
  271.  
  272.     (void) fprintf(outputfile, "gsave\n");
  273.     (void) fprintf(outputfile, "%g %g translate\n",
  274.     72.0*(.69+col*7.5/((float) pagefactor)), 
  275.     72.0*(.25+(pagefactor-row-1)*10.5/((float) pagefactor)));
  276.     (void) fprintf(outputfile, "%g %g scale\n",
  277.         1.0/((float) pagefactor)/1.17,
  278.         1.0/((float) pagefactor)/1.08);
  279.     (void) fprintf(outputfile, "outline\n");
  280.  
  281.     (void) fprintf(outputfile, "/%s findfont\n", titlefont);
  282.     (void) fprintf(outputfile, "16 scalefont\n");
  283.     (void) fprintf(outputfile, "setfont\n");
  284.  
  285.     (void) fprintf(outputfile, "(%s) 36 770 ms\n", title);
  286. #if 0
  287.     (void) fprintf(outputfile, "(%s) 180 10 ms\n", timestr);
  288. #endif
  289.     (void) fprintf(outputfile, "(Page %ld) 515 770 ms\n",
  290.         pagenumber++);
  291.  
  292.     (void) fprintf(outputfile, "/%s findfont\n", bodyfont);
  293.     (void) fprintf(outputfile, "10.8 scalefont\n");
  294.     (void) fprintf(outputfile, "setfont\n");
  295.  
  296.     (void) fprintf(outputfile, "36 756 M\n");
  297.     line = 0;
  298.     while (line < 66) {
  299.     if (insideline == 0) {
  300.         if (fgets(buffer, BUFSIZ, printfile) == NULL) {
  301.         (void) fprintf(outputfile, "grestore\n");
  302.         (void) fprintf(outputfile, "showpage\n");
  303.         return 1;
  304.         }
  305.     }
  306.     insideline = copyline(buffer, outbuf);
  307.     (void) fprintf(outputfile, "(%s) ns\n", outbuf);
  308.     line++;
  309.     }
  310.     (void) fprintf(outputfile, "grestore\n");
  311.     return 0;
  312. }
  313.  
  314. copyline(buffer, outbuf)
  315. char *buffer, *outbuf;
  316. {
  317.     static int bufcount = 0;
  318.     int charcount;
  319.  
  320.     charcount = 0;
  321.     while (charcount < 80) {
  322.     switch(buffer[bufcount]) {
  323.         case '\f':
  324.         line = 66;
  325.         *outbuf = 0;
  326.         bufcount = 0;
  327.         return 0;
  328.         case '\t':
  329.         bufcount++;
  330.         *outbuf++ = ' ';
  331.         charcount++;
  332.         while (charcount & 7) {
  333.             *outbuf++ = ' ';
  334.             charcount++;
  335.         }
  336.         charcount--;
  337.         break;
  338.         case '\\':
  339.         *outbuf++ = '\\';
  340.         *outbuf++ = '\\';
  341.         bufcount++;
  342.         break;
  343.         case '(':
  344.         *outbuf++ = '\\';
  345.         *outbuf++ = '(';
  346.         bufcount++;
  347.         break;
  348.         case ')':
  349.         *outbuf++ = '\\';
  350.         *outbuf++ = ')';
  351.         bufcount++;
  352.         break;
  353.         case '\n':
  354.         *outbuf = 0;
  355.         bufcount = 0;
  356.         return 0;
  357.         break;
  358.         default:
  359.             if (buffer[bufcount] < ' ') {
  360.             *outbuf++ = '^';
  361.             *outbuf++ = 'A' + buffer[bufcount++];
  362.         } else
  363.             *outbuf++ = buffer[bufcount++];
  364.         break;
  365.     }
  366.     *outbuf = 0;
  367.     charcount++;
  368.     }
  369.     *outbuf = 0;
  370.     return 1;
  371. }
  372.  
  373. printheaderstuff()
  374. {
  375.     (void) fprintf(outputfile, "%%!PS-Adobe-1.0\n");
  376.     (void) fprintf(outputfile, "%%%%Pages: (atend)\n");
  377.     (void) fprintf(outputfile, "%%%%DocumentFonts: %s %s\n", titlefont,
  378.     bodyfont);
  379.     (void) fprintf(outputfile, "%%%%CreationDate: %s\n", timestr);
  380.     (void) fprintf(outputfile, "%%%%EndComments\n");
  381.     (void) fprintf(outputfile, "/%s findfont\n", bodyfont);
  382.     (void) fprintf(outputfile, "10.8 scalefont\n");
  383.     (void) fprintf(outputfile, "setfont\n");
  384.     (void) fprintf(outputfile, "/ns\n");
  385.     (void) fprintf(outputfile, "  { currentpoint exch pop\n");
  386.     (void) fprintf(outputfile, "    11.2 sub 36 exch moveto show} bind def\n");
  387.     (void) fprintf(outputfile, "/ms { moveto show } bind def\n");
  388.     (void) fprintf(outputfile, "/M /moveto load def\n");
  389.     (void) fprintf(outputfile, "/L /lineto load def\n");
  390.     (void) fprintf(outputfile, "/outline\n");
  391.     (void) fprintf(outputfile, " {\n");
  392.     (void) fprintf(outputfile, "      .1 setlinewidth\n");
  393.     (void) fprintf(outputfile, "      0.8 setgray\n");
  394.     (void) fprintf(outputfile, "      gsave\n");
  395.     (void) fprintf(outputfile, "    7.2 -7.2 translate\n");
  396.     (void) fprintf(outputfile, "      newpath\n");
  397.     (void) fprintf(outputfile, "      0 0 M\n");
  398.     (void) fprintf(outputfile, "      0 792 L\n");
  399.     (void) fprintf(outputfile, "      612 792 L\n");
  400.     (void) fprintf(outputfile, "      612 0 L\n");
  401.     (void) fprintf(outputfile, "      closepath\n");
  402.     (void) fprintf(outputfile, "      fill\n");
  403.     (void) fprintf(outputfile, "      grestore\n");
  404.     (void) fprintf(outputfile, "      1.0 setgray\n");
  405.     (void) fprintf(outputfile, "      newpath\n");
  406.     (void) fprintf(outputfile, "      0 0 M\n");
  407.     (void) fprintf(outputfile, "      0 792 L\n");
  408.     (void) fprintf(outputfile, "      612 792 L\n");
  409.     (void) fprintf(outputfile, "      612 0 L\n");
  410.     (void) fprintf(outputfile, "      closepath\n");
  411.     (void) fprintf(outputfile, "      gsave fill grestore\n");
  412.     (void) fprintf(outputfile, "      0.0 setgray\n");
  413.     (void) fprintf(outputfile, "      stroke\n");
  414.     (void) fprintf(outputfile, " } bind def\n");
  415.     (void) fprintf(outputfile, "%%%%EndProlog\n");
  416. }
  417. printtrailerstuff()
  418. {
  419.     (void) fprintf(outputfile, "%%%%Pages: %d\n", ordinal);
  420. }
  421.